///
/// https://rustwiki.org/zh-CN/rust-by-example/hello/print.html
///

fn main() {
    assert_eq!(format!("{1} {} {0} {} {1}", 1, 2), "2 1 1 2 2"); // => "2 1 1 2"
                                                                 // 按索引
    assert_eq!("1 of 10, 1", format!("{0} of {1}, {0}", 1, 10));
    // 按变量名
    assert_eq!(
        "1 of 10",
        format!("{current} of {total}", current = 1, total = 10)
    );

    // 设置特殊格式
    // - ``, which uses the `Display` trait
    // - `?`, which uses the `Debug` trait
    // - `e`, which uses the `LowerExp` trait
    // - `E`, which uses the `UpperExp` trait
    // - `o`, which uses the `Octal` trait
    // - `p`, which uses the `Pointer` trait
    // - `b`, which uses the `Binary` trait
    // - `x`, which uses the `LowerHex` trait
    // - `X`, which uses the `UpperHex` trait
    assert_eq!("abc", format!("{:}", "abc"));
    assert_eq!("\"abc\"", format!("{:?}", "abc"));
    assert_eq!("9e0", format!("{:e}", 9));
    assert_eq!("9E0", format!("{:E}", 9));
    assert_eq!("11", format!("{:o}", 9));
    assert!((format!("{:p}", "xyz".as_ptr()) as String).starts_with("0x"));
    assert_eq!("11", format!("{:b}", 3));
    assert_eq!("a", format!("{:x}", 10));
    assert_eq!("A", format!("{:X}", 10));

    // 右对齐
    assert_eq!(
        "       abc",
        format!("{str:>width$}", str = "abc", width = 10)
    );
    // 对数字前补0
    assert_eq!("0007", format!("{str:>0width$}", str = 7, width = 4));
    assert_eq!("0001", format!("{number:>0width$}", number = 1, width = 4));
    // 字符串补
    assert_eq!("0001", format!("{s:0>w$}", s = "1", w = 4));
    assert_eq!("-1--", format!("{s:-^w$}", s = "1", w = 4));
    assert_eq!("--1--", format!("{s:-^w$}", s = "1", w = 5));
    assert_eq!("0001", format!("{s:0>4}", s = "1"));
    assert_eq!("-1--", format!("{s:-^4}", s = "1"));
    assert_eq!("--1--", format!("{s:-^5}", s = "1"));

    // 所有这些打印 "Hello x !"
    println!("Hello {:10}!", "x");
    println!("Hello {:1$}!", "x", 10);
    println!("Hello {1:0$}!", 10, "x");
    println!("Hello {:width$}!", "x", width = 5);
    //如果命名参数没有出现在参数列表中，format! 将引用当前作用域中的同名变量。
    let width = 5;
    println!("Hello {:width$}!", "x");
    // println!("hello, x", no_use=3);
    assert_eq!(
        format!("hello {name} {} {0}", name = "lishixi"),
        "hello lishixi lishixi lishixi"
    );

    //pi小数点2位
    let pi = 3.141592;
    assert_eq!(format!("{:.2}", pi),"3.14");
}
